﻿using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;

namespace ml_testing_BingTrans
{
    public class TransHttpHelper
    {
         


        public static string GetTranslations(string textVal)
        {
            var  sbTrans = new StringBuilder();
            string appId = "C1D1CDEB53FDFCC57E7F911E872CD85B0ACF46E3"; //go to http://msdn.microsoft.com/en-us/library/hh454950.aspx to obtain an Access Token.
            string uri = "http://api.microsofttranslator.com/v2/Http.svc/GetTranslations?appId=" + appId +
                         "&text=" + textVal + "&from=" + "zh-CHS" + "&to=" + "en" + "&maxTranslations=5";

            string requestBody = GenerateTranslateOptionsRequestBody("", "defaultUser");

            var req = (HttpWebRequest) WebRequest.Create(uri);
            req.ContentType = "text/xml";
            req.Method = "POST";
            //req.Proxy = new WebProxy(); define the name of your proxy here if needed
            using (Stream stream = req.GetRequestStream())
            {
                byte[] arrBytes = Encoding.ASCII.GetBytes(requestBody);
                stream.Write(arrBytes, 0, arrBytes.Length);
            }

            WebResponse response = null;
            try
            {
                response = req.GetResponse();
                using (Stream respStream = response.GetResponseStream())
                {
                    var rdr = new StreamReader(respStream, Encoding.ASCII);
                    string strResponse = rdr.ReadToEnd();

                    GetTranslationsResponse getTranslationsResponse =
                        TranslationDeserializer.Deserialize(new GetTranslationsResponse(), strResponse);

                    string formattedResponse = String.Format("Source Language: {0} State: {1}\n",
                                                             getTranslationsResponse.From,
                                                             getTranslationsResponse.State);

                    foreach (TranslationMatch res in getTranslationsResponse.Translations)
                    {
                        if (res.Error != null)
                        {
                            formattedResponse += String.Format("Error: {0}", res.Error);
                        }
                        else
                        {
                            formattedResponse +=
                                String.Format(
                                    "Source: {0} Match Degree: {1} Translated: {2} Rating: {3} Count: {4}"
                                    , res.MatchedOriginalText
                                    , res.MatchDegree
                                    , res.TranslatedText
                                    , res.Rating
                                    , res.Count);
                            sbTrans.Append(res.TranslatedText + "\r\n");
                        }
                        formattedResponse += "\n";
                    }
                    Console.WriteLine(formattedResponse);
                }
            }
            catch (WebException e)
            {
                ProcessWebException(e, "Failed to get translations");
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                    response = null;
                }
            }
            return sbTrans.ToString();
        }

        // builds the outter xml body
        private static string GenerateTranslateOptionsRequestBody(string uri, string user)
        {
            string body =
                "<TranslateOptions xmlns=\"http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2\">" +
                "  <Category>general</Category>" +
                "  <ContentType>text/plain</ContentType>" +
                "  <ReservedFlags />" +
                "  <State />" +
                "  <Uri>[Uri]</Uri>" +
                "  <User>[User]</User>" +
                "</TranslateOptions>";

            // replace the tags
            body = body.Replace("[Uri]", uri);
            body = body.Replace("[User]", user);
            return body;
        }

        private static void ProcessWebException(WebException e, string message)
        {
            Console.WriteLine("{0}: {1}", message, e);

            // Obtain detailed error information
            string strResponse = string.Empty;
            using (var response = (HttpWebResponse) e.Response)
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    using (var sr = new StreamReader(responseStream, Encoding.ASCII))
                    {
                        strResponse = sr.ReadToEnd();
                    }
                }
            }
            Console.WriteLine("Http status code={0}, error message={1}", e.Status, strResponse);
        }

        #region Nested type: ArrayOfGetTranslationsResponse

        /// <summary>
        /// Class for GetTranslationsArray
        /// </summary>
        [Serializable]
        [XmlType(Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2")]
        [XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2", IsNullable = true)]
        public class ArrayOfGetTranslationsResponse
        {
            [XmlElement("GetTranslationsResponse", IsNullable = true)]
            public GetTranslationsResponse[] GetTranslationsResponse { get; set; }
        }

        #endregion

        #region Nested type: ArrayOfTranslationMatch

        [Serializable]
        [XmlType(Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2")]
        [XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2", IsNullable = true)]
        public class ArrayOfTranslationMatch
        {
            [XmlElement("TranslationMatch", IsNullable = true)]
            public TranslationMatch[] TranslationMatch { get; set; }
        }

        #endregion

        #region Nested type: GetTranslationsResponse

        /// <summary>
        /// Classes for GetTranslations method deserilization
        /// </summary>
        [Serializable]
        [XmlType(Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2")]
        [XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2", IsNullable = true)]
        public class GetTranslationsResponse
        {
            [XmlElement(IsNullable = true)]
            public string From { get; set; }

            [XmlElement(IsNullable = true)]
            public string State { get; set; }

            [XmlArray(IsNullable = true)]
            public TranslationMatch[] Translations { get; set; }
        }

        #endregion

        #region Nested type: TranslationDeserializer

        /// <summary>
        /// Utility class used for deserialising responses
        /// </summary>
        public static class TranslationDeserializer
        {
            /// <summary>
            /// Deserilizes the specified response type.
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="responseType">Type of the response.</param>
            /// <param name="restResponse">The rest response.</param>
            /// <returns></returns>
            public static T Deserialize<T>(T responseType, string restResponse)
            {
                restResponse = @"<?xml version=""1.0"" encoding=""UTF-8""?>" + restResponse;

                var serializer = new XmlSerializer(typeof (T));

                using (var read = new StringReader(restResponse))
                using (var reader = new XmlTextReader(read))
                    responseType = (T) serializer.Deserialize(reader);

                return responseType;
            }
        }

        #endregion

        #region Nested type: TranslationMatch

        [Serializable]
        [XmlType(Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2")]
        [XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2", IsNullable = true)]
        public class TranslationMatch
        {
            public int Count { get; set; }

            [XmlElement(IsNullable = true)]
            public string Error { get; set; }

            public int MatchDegree { get; set; }

            [XmlElement(IsNullable = true)]
            public string MatchedOriginalText { get; set; }

            public int Rating { get; set; }

            [XmlElement(IsNullable = true)]
            public string TranslatedText { get; set; }
        }

        #endregion

        

    }
}